local game = require "club.threecard.blackjack"
local Vector3 = CS.UnityEngine.Vector3

local config = game.pokerlib.core.poker_container_config.new()

config.show_hand = true;
config.ope_valid = false;

config.hand_poker_class = game.require "poker_controller.poker"

local map = {3, 2, 1};
local angle = 10;
local angles = 
{
    [3] = {angle, 0, -angle};
    [2] = {angle/2, -angle/2};
    [1] = {0};
}
config.hand_align = function(pokers, root)
    if pokers == nil or #pokers == 0 then
        return;
    end

    local total_count = 0;
    for _, c in ipairs(map) do
        total_count = total_count + c;
    end

    if #pokers > total_count then
        game.gamelib.log.error("手牌可排列最大数量超过："..total_count)
        return;
    end

    local row_count = 0;
    local poker_count = #pokers;
    local temp_pokers = {};
    local temp_index = 0;
    for i, c in ipairs(map) do
        temp_pokers[i] = {};
        row_count = row_count + 1;
        poker_count = poker_count - c;

        for a = 1, c do
            temp_index = temp_index + 1;
            if pokers[temp_index] then
                table.insert(temp_pokers[i], pokers[temp_index]);
            end
        end
        
        if poker_count <= 0 then
            break;
        end
    end

    local y_space = 100;
    local x_space = 45;

    local start_y = 0;
    if row_count %2 == 0 then
        start_y = math.floor(row_count/2) * y_space - 0.5 * y_space;
    else
        start_y =  math.floor(row_count/2) * y_space;
    end

    for i = 1, row_count do
        local y = start_y - (i-1) * y_space;
        local p = temp_pokers[i];
        local start_x = 0;
        if #p % 2 == 0 then
            start_x = -math.floor( #p/2 ) * x_space + 0.5 * x_space;
        else
            start_x = -math.floor( #p/2 ) * x_space;
        end

        for j, poker in ipairs(p) do
            local x = start_x + (j - 1) * x_space;
            poker:set_parent(root);
            poker:set_position(Vector3(x, y, 0));
            poker:set_aslastsibling();

            poker.transform.localEulerAngles = Vector3(0, 0, angles[#p][j]);
        end
    end
end

local function a_in_b(a, b)
    for _, v in ipairs(b) do
        if a == v then
            return true;
        end
    end

    return false;
end

local DOTween = CS.DG.Tweening.DOTween
local empty_poker_data = config.poker_data_class.new(-1);

config.mopai_anim = function(poker_container, serverValueTable, over_handler)
    local start_pos = poker_container.start_pos;
    local interval = 0.15;
    local anim_time = 0.2;
    game.coroutine.ingame_start(function()
        poker_container:insert_hand(serverValueTable);
        local to_anim_pokers = {pokers = {}, values = {}};
        for _, poker in ipairs(poker_container.hand) do
            if a_in_b(poker.data.server_value, serverValueTable) then
                table.insert(to_anim_pokers.pokers, poker);
                table.insert(to_anim_pokers.values, poker.data.server_value);
                poker:set_data(empty_poker_data);
                poker:hide();
            end
        end

        local left_count = #to_anim_pokers.pokers;
        for index, poker in ipairs(to_anim_pokers.pokers) do
            local end_pos = poker.transform.position;
            poker.transform.position = start_pos;
            poker:show();
            game.audio.post("blackjack:send")
            DOTween.To(function(value)
                poker.transform.localEulerAngles = Vector3(0, 0, value);
            end, -360*1, poker.transform.localEulerAngles.z, anim_time)
            local value = to_anim_pokers.values[index];
            poker.transform:DOMove(end_pos, anim_time)
            :OnComplete(function() 
                if poker.data.server_value ~= value then
                    local poker_data = poker_container.config.poker_data_class.new(value);
                    poker:flip(poker_data, function() left_count = left_count - 1; end);
                end
            end)

            game.coroutine.wait(interval);
        end

        while left_count > 0 do
            game.coroutine.step();
        end

        if over_handler then
            over_handler();
        end
    end)
end

local banker_config = game.pokerlib.core.poker_container_config.new()
config.banker_config = banker_config

banker_config.hand_align = function(pokers, root)
    local align_helper = game.pokerlib.core.align_helper;
    align_helper.Align(pokers, root, align_helper.EPivot.middle, 70, 0, 100);
    for _, poker in ipairs(pokers) do
        poker.transform.localEulerAngles = Vector3.zero;
    end
end

banker_config.mopai_anim = config.mopai_anim;
banker_config.show_hand = true;
banker_config.ope_valid = false;
banker_config.hand_poker_class = game.require "poker_controller.poker"

return config